
#include "qy7zPackage.h"
#include "qyFile.h"
#include "Types.h"

//-----------------------------------------------------------------------
qy7zPackage::qy7zPackage()
{

}

//-----------------------------------------------------------------------
qy7zPackage::~qy7zPackage()
{

}

//-----------------------------------------------------------------------
bool qy7zPackage::SetPackageFile( const qyString &path )
{
	m_path = path;
	SRes res;

	InFile_Open( &m_archiveStream.file, m_path.c_str() );

	FileInStream_CreateVTable( &m_archiveStream );
	LookToRead_CreateVTable( &m_lookStream, False );

	m_lookStream.realStream = &m_archiveStream.s;
	LookToRead_Init( &m_lookStream );

	m_allocImp.Alloc = SzAlloc;
	m_allocImp.Free = SzFree;

	m_allocTempImp.Alloc = SzAllocTemp;
	m_allocTempImp.Free = SzFreeTemp;

	CrcGenerateTable();

	SzArEx_Init( &m_db );
	res = SzArEx_Open( &m_db, &m_lookStream.s, &m_allocImp, &m_allocTempImp );
	if ( res != SZ_OK )
	{
		return false;
	}

	for ( unsigned i = 0; i < m_db.db.NumFiles; ++i )
	{
		CSzFileItem *fi = m_db.db.Files + i;
		if ( fi->Size >= 0 && !fi->IsDir )
		{
			std::string name = fi->Name;
			FileItem item;
			item.fp = i;
			item.size = fi->Size;
			item.crc = (fi->Size > 0)?fi->FileCRC : 0;
			m_fileItems[name] = item;
		}
	}

	return true;
}

//-----------------------------------------------------------------------
bool qy7zPackage::OpenReadFile( qyFile &file, const qyString &relativePath )
{
	if ( m_fileItems.find( relativePath ) == m_fileItems.end() )
		return false;

	FileItem item = m_fileItems[relativePath];
	size_t offset;
	size_t outSizeProcessed;

	SRes res;

	uint32_t blockIndex = 0xFFFFFFFF;
	BYTE *outBuffer = 0;
	size_t outBuffSize = 0;

	res = SzAr_Extract( &m_db, &m_lookStream.s, item.fp,
		&blockIndex, &outBuffer, &outBuffSize, 
		&offset, &outSizeProcessed, 
		&m_allocImp, &m_allocTempImp );

	if ( res != SZ_OK )
		return false;
	
	file.AllockMemChunk( outSizeProcessed );
	memcpy( file.GetMemChunk(), outBuffer + offset, outSizeProcessed );

	IAlloc_Free( &m_allocImp, outBuffer );
	
	return true;
}

